bitkeeper revision 1.1108.35.3 (4109068aJLiAygvPcLaayrwLbvNnyw)
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Thu, 29 Jul 2004 14:15:38 +0000 (14:15 +0000)
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Thu, 29 Jul 2004 14:15:38 +0000 (14:15 +0000)
Add vif and vbd commands, including adding vbds to
an existing domain.

tools/python/xen/xend/XendDomain.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/server/blkif.py
tools/python/xen/xend/server/netif.py
tools/python/xen/xm/main.py

index 3a07b49294c5591234809a703b0dbc71b9524bc9..ce00717eb7300f1b94ae0765777c94bacd3379bd 100644 (file)
@@ -417,7 +417,10 @@ class XendDomain:
         """
         dominfo = self.domain_lookup(id)
         eserver.inject('xend.domain.unpause', dominfo.name)
-        return xc.domain_unpause(dom=dominfo.dom)
+        try:
+            return xc.domain_unpause(dom=dominfo.dom)
+        except Exception, ex:
+            raise XendError(str(ex))
     
     def domain_pause(self, id):
         """Pause domain execution.
@@ -426,7 +429,10 @@ class XendDomain:
         """
         dominfo = self.domain_lookup(id)
         eserver.inject('xend.domain.pause', dominfo.name)
-        return xc.domain_pause(dom=dominfo.dom)
+        try:
+            return xc.domain_pause(dom=dominfo.dom)
+        except Exception, ex:
+            raise XendError(str(ex))
     
     def domain_shutdown(self, id, reason='poweroff'):
         """Shutdown domain (nicely).
@@ -581,45 +587,66 @@ class XendDomain:
         @param cpu: cpu number
         """
         dominfo = self.domain_lookup(id)
-        return xc.domain_pincpu(itn(dominfo.id), cpu)
+        try:
+            return xc.domain_pincpu(itn(dominfo.id), cpu)
+        except Exception, ex:
+            raise XendError(str(ex))
 
     def domain_cpu_bvt_set(self, id, mcuadv, warp, warpl, warpu):
         """Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
         """
         dominfo = self.domain_lookup(id)
-        return xc.bvtsched_domain_set(dom=dominfo.dom, mcuadv=mcuadv,
-                                      warp=warp, warpl=warpl, warpu=warpu)
+        try:
+            return xc.bvtsched_domain_set(dom=dominfo.dom, mcuadv=mcuadv,
+                                          warp=warp, warpl=warpl, warpu=warpu)
+        except Exception, ex:
+            raise XendError(str(ex))
 
     def domain_cpu_bvt_get(self, id):
         """Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
         """
         dominfo = self.domain_lookup(id)
-        return xc.bvtsched_domain_get(dominfo.dom)
+        try:
+            return xc.bvtsched_domain_get(dominfo.dom)
+        except Exception, ex:
+            raise XendError(str(ex))
     
     def domain_cpu_fbvt_set(self, id, mcuadv, warp, warpl, warpu):
         """Set FBVT (Fair Borrowed Virtual Time) scheduler parameters for a domain.
         """
         dominfo = self.domain_lookup(id)
-        return xc.fbvtsched_domain_set(dom=dominfo.dom, mcuadv=mcuadv,
-                                       warp=warp, warpl=warpl, warpu=warpu)
+        try:
+            return xc.fbvtsched_domain_set(dom=dominfo.dom, mcuadv=mcuadv,
+                                           warp=warp, warpl=warpl, warpu=warpu)
+        except Exception, ex:
+            raise XendError(str(ex))
 
     def domain_cpu_fbvt_get(self, id):
         """Get FBVT (Fair Borrowed Virtual Time) scheduler parameters for a domain.
         """
         dominfo = self.domain_lookup(id)
-        return xc.fbvtsched_domain_get(dominfo.dom)
+        try:
+            return xc.fbvtsched_domain_get(dominfo.dom)
+        except Exception, ex:
+            raise XendError(str(ex))
         
     def domain_cpu_atropos_set(self, id, period, slice, latency, xtratime):
         """Set Atropos scheduler parameters for a domain.
         """
         dominfo = self.domain_lookup(id)
-        return xc.atropos_domain_set(dominfo.dom, period, slice, latency, xtratime)
+        try:
+            return xc.atropos_domain_set(dominfo.dom, period, slice, latency, xtratime)
+        except Exception, ex:
+            raise XendError(str(ex))
 
     def domain_cpu_atropos_get(self, id):
         """Get Atropos scheduler parameters for a domain.
         """
         dominfo = self.domain_lookup(id)
-        return xc.atropos_domain_get(dominfo.dom)
+        try:
+            return xc.atropos_domain_get(dominfo.dom)
+        except Exception, ex:
+            raise XendError(str(ex))
 
     def domain_device_create(self, id, devconfig):
         """Create a new device for a domain.
@@ -711,7 +738,10 @@ class XendDomain:
         @param op:  operation
         """
         dominfo = self.domain_lookup(id)
-        return xc.shadow_control(dominfo.dom, op)
+        try:
+            return xc.shadow_control(dominfo.dom, op)
+        except Exception, ex:
+            raise XendError(str(ex))
 
     def domain_maxmem_set(self, id, mem):
         """Set the memory limit for a domain.
@@ -722,7 +752,10 @@ class XendDomain:
         """
         dominfo = self.domain_lookup(id)
         maxmem = int(mem) * 1024
-        return xc.domain_setmaxmem(dominfo.dom, maxmem_kb = maxmem)
+        try:
+            return xc.domain_setmaxmem(dominfo.dom, maxmem_kb = maxmem)
+        except Exception, ex:
+            raise XendError(str(ex))
 
 
 def instance():
index 1a9b74190aea3ae86a3590276d2a788c48c80f57..e7128c06c0d092eb45ff552171711dd7cd754059 100644 (file)
@@ -622,7 +622,10 @@ class XendDomainInfo:
         if chan:
             log.debug("Closing channel to domain %d", self.dom)
             chan.close()
-        return xc.domain_destroy(dom=self.dom)
+        try:
+            return xc.domain_destroy(dom=self.dom)
+        except Exception, err:
+            log.exception("Domain destroy failed: ", self.name)
 
     def cleanup(self):
         """Cleanup vm resources: release devices.
@@ -855,6 +858,7 @@ class XendDomainInfo:
         if self.restart_time is not None:
             tdelta = tnow - self.restart_time
             if tdelta < self.MINIMUM_RESTART_TIME:
+                self.restart_cancel()
                 msg = 'VM %s restarting too fast' % self.name
                 log.error(msg)
                 raise VmError(msg)
@@ -1036,7 +1040,6 @@ def vm_dev_vbd(vm, val, index):
     """
     if vm.blkif_backend:
         raise VmError('vbd: vbd in blkif backend domain')
-    vdev = vm.next_device_index('vif')
     uname = sxp.child_value(val, 'uname')
     if not uname:
         raise VmError('vbd: Missing uname')
@@ -1047,8 +1050,9 @@ def vm_dev_vbd(vm, val, index):
     log.debug("Creating vbd dom=%d uname=%s dev=%s", vm.dom, uname, dev)
     defer = make_disk(vm.dom, uname, dev, mode, vm.recreate)
     def fn(vbd):
-        dev = xend.blkif_dev(vm.dom, vdev)
-        vm.add_device('vbd', dev)
+        vbd.dev = dev
+        vbd.uname = uname
+        vm.add_device('vbd', vbd)
         return vbd
     defer.addCallback(fn)
     return defer
index 8bf9a90d12faadb4ac121c3c91cfc51d84f2fdc7..5c62a81e0e521bbfef75a9f5ac7bf8291e021f44 100755 (executable)
@@ -160,13 +160,15 @@ class BlkifControllerFactory(controller.ControllerFactory):
         else:
             pass
     
-    def respond_be_vbd_create(self, msg, d):
+    def respond_be_vbd_create(self, msg, dev, d):
         """Response handler for a be_vbd_create message.
         Tries to grow the vbd, and passes the deferred I{d} on for
         the grow to call.
 
         @param msg: message
         @type  msg: xu message
+        @param dev: device
+        @type  dev: BlkDev
         @param d: deferred to call
         @type  d: Deferred
         """
@@ -174,17 +176,19 @@ class BlkifControllerFactory(controller.ControllerFactory):
         blkif = self.getInstanceByDom(val['domid'])
         if blkif:
             d1 = defer.Deferred()
-            d1.addCallback(self.respond_be_vbd_grow, d)
+            d1.addCallback(self.respond_be_vbd_grow, dev, d)
             if d: d1.addErrback(d.errback)
             blkif.send_be_vbd_grow(val['vdevice'], response=d1)
         else:
             pass
     
-    def respond_be_vbd_grow(self, msg, d):
+    def respond_be_vbd_grow(self, msg, dev, d):
         """Response handler for a be_vbd_grow message.
 
         @param msg: message
         @type  msg: xu message
+        @param dev: device
+        @type  dev: BlkDev
         @param d: deferred to call
         @type  d: Deferred or None
         """
@@ -192,7 +196,7 @@ class BlkifControllerFactory(controller.ControllerFactory):
         # Check status?
         if self.attached:
             if d:
-                d.callback(0)
+                d.callback(dev)
         else:
             self.reattachDevice(val['domid'], val['vdevice'])
 
@@ -216,6 +220,8 @@ class BlkDev(controller.Dev):
 
     def __init__(self, ctrl, vdev, mode, segment):
         controller.Dev.__init__(self,  segment['device'], ctrl)
+        self.dev = None
+        self.uname = None
         self.vdev = vdev
         self.mode = mode
         self.device = segment['device']
@@ -232,6 +238,10 @@ class BlkDev(controller.Dev):
                ['vdev', self.vdev],
                ['device', self.device],
                ['mode', self.mode]]
+        if self.dev:
+            val.append(['dev', self.dev])
+        if self.uname:
+            val.append(['uname', self.uname])
         return val
 
     def destroy(self):
@@ -292,6 +302,7 @@ class BlkifController(controller.Controller):
 
     def attachDevice(self, vdev, mode, segment, recreate=0):
         """Attach a device to the specified interface.
+        On success the returned deferred will be called with the device.
 
         @param vdev:     device index
         @type  vdev:     int
@@ -308,10 +319,10 @@ class BlkifController(controller.Controller):
         if not dev: return -1
         d = defer.Deferred()
         if recreate:
-            d.callback(self)
+            d.callback(dev)
         else:
             d1 = defer.Deferred()
-            d1.addCallback(self.factory.respond_be_vbd_create, d)
+            d1.addCallback(self.factory.respond_be_vbd_create, dev, d)
             d1.addErrback(d.errback)
             self.send_be_vbd_create(vdev, response=d1)
         return d
@@ -335,7 +346,7 @@ class BlkifController(controller.Controller):
         for dev in self.devices.values():
             dev.attached = 0
             d1 = defer.Deferred()
-            d1.addCallback(self.factory.respond_be_vbd_create, None)
+            d1.addCallback(self.factory.respond_be_vbd_create, None, None)
             self.send_be_vbd_create(vdev, response=d1)
 
     def reattachDevice(self, vdev):
index cce11f621e52ddd9b3e2ba8dfc5a8cd15fde1aea..3f51492ace6fbb4ef4891209dfefc7eef05412f5 100755 (executable)
@@ -122,7 +122,7 @@ class NetDev(controller.Dev):
         self.mac = None
         self.bridge = None
         self.script = None
-        self.ipaddr = None
+        self.ipaddr = []
         
         vmac = sxp.child_value(config, 'mac')
         if not vmac: raise XendError("invalid mac")
index d05a29d0380ef477fdc772a30f65e8ed9cceeec4..94fc53a1f9b80ce5c61f8deadf5c8f1ca06230ce 100644 (file)
@@ -209,6 +209,20 @@ class GroupConsole(Group):
 
 xm.group(GroupConsole)
 
+class GroupVbd(Group):
+
+    name = "vbd"
+    info = "Commands related to virtual block devices:"
+
+xm.group(GroupVbd)
+
+class GroupVif(Group):
+
+    name = "vif"
+    info = "Commands related to virtual network interfaces:"
+
+xm.group(GroupVif)
+
 class ProgHelp(Prog):
 
     name = "help"
@@ -630,5 +644,86 @@ class ProgLog(Prog):
 
 xm.prog(ProgLog)
 
+class ProgVifList(Prog):
+    group = 'vif'
+    name  = 'vif-list'
+    info  = """List virtual network interfaces for a domain."""
+
+    def help(self, args):
+        print args[0], "DOM"
+        print "\nList virtual network interfaces for domain DOM"
+
+    def main(self, args):
+        if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
+        dom = args[1]
+        for x in server.xend_domain_vifs(dom):
+            sxp.show(x)
+            print
+
+xm.prog(ProgVifList)
+
+class ProgVbdList(Prog):
+    group = 'vbd'
+    name  = 'vbd-list'
+    info  = """List virtual block devices for a domain."""
+
+    def help(self, args):
+        print args[0], "DOM"
+        print "\nList virtual block devices for domain DOM"
+
+    def main(self, args):
+        if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
+        dom = args[1]
+        for x in server.xend_domain_vbds(dom):
+            sxp.show(x)
+            print
+
+xm.prog(ProgVbdList)
+
+class ProgVbdCreate(Prog):
+    group = 'vbd'
+    name  = 'vbd-create'
+    info = """Create a new virtual block device for a domain"""
+
+    def help(self, args):
+        print args[0], "DOM UNAME DEV MODE"
+        print """
+Create a virtual block device for a domain.
+
+  UNAME - device to export, e.g. phys:hda2
+  DEV   - device name in the domain, e.g. xda1
+  MODE  - access mode: r for read, w for read-write
+"""
+
+    def main(self, args):
+        if len(args) != 5: self.err("%s: Invalid argument(s)" % args[0])
+        dom = args[1]
+        vbd = ['vbd',
+               ['uname', args[2]],
+               ['dev',   args[3]],
+               ['mode',  args[4]]]
+        server.xend_domain_device_create(dom, vbd)
+
+xm.prog(ProgVbdCreate)
+
+class ProgVbdDestroy(Prog):
+    group = 'vbd'
+    name = 'vbd-destroy'
+    info = """Destroy a domain's virtual block device"""
+
+    def help(self, args):
+        print args[0], "DOM DEV"
+        print """
+Destroy vbd DEV attached to domain DOM. Detaches the device
+from the domain, but does not destroy the device contents."""
+
+    def main(self, args):
+        if len(args!=3): self.err("%s: Invalid argument(s)" % args[0])
+        dom = args[1]
+        dev = args[2]
+        sever.xend_domain_device_destroy(dom, "vbd", dev)
+
+xm.prog(ProgVbdDestroy)
+
 def main(args):
     xm.main(args)